package handles

import (
	"context"

	"github.com/alist-org/alist/v3/internal/conf"
	"github.com/alist-org/alist/v3/internal/model"
	"github.com/alist-org/alist/v3/internal/search"
	"github.com/alist-org/alist/v3/internal/setting"
	"github.com/alist-org/alist/v3/server/common"
	"github.com/gin-gonic/gin"
	log "github.com/sirupsen/logrus"
)

type UpdateIndexReq struct {
	Paths    []string `json:"paths"`     // 需要更新的路径列表
	MaxDepth int      `json:"max_depth"` // 最大索引深度
	//IgnorePaths []string `json:"ignore_paths"` // 忽略路径(已注释)
}

// BuildIndex 构建全量索引
func BuildIndex(c *gin.Context) {
	if search.Running() {
		common.ErrorStrResp(c, "索引正在构建中", 400)
		return
	}
	go func() {
		ctx := context.Background()
		err := search.Clear(ctx)
		if err != nil {
			log.Errorf("清除索引失败: %+v", err)
			return
		}
		err = search.BuildIndex(context.Background(), []string{"/"},
			conf.SlicesMap[conf.IgnorePaths], setting.GetInt(conf.MaxIndexDepth, 20), true)
		if err != nil {
			log.Errorf("构建索引失败: %+v", err)
		}
	}()
	common.SuccessResp(c)
}

// UpdateIndex 更新指定路径的索引
func UpdateIndex(c *gin.Context) {
	var req UpdateIndexReq
	if err := c.ShouldBind(&req); err != nil {
		common.ErrorResp(c, err, 400)
		return
	}
	if search.Running() {
		common.ErrorStrResp(c, "索引正在构建中", 400)
		return
	}
	if !search.Config(c).AutoUpdate {
		common.ErrorStrResp(c, "当前索引不支持更新操作", 400)
		return
	}
	go func() {
		ctx := context.Background()
		for _, path := range req.Paths {
			err := search.Del(ctx, path)
			if err != nil {
				log.Errorf("删除路径 %s 索引失败: %+v", path, err)
				return
			}
		}
		err := search.BuildIndex(context.Background(), req.Paths,
			conf.SlicesMap[conf.IgnorePaths], req.MaxDepth, false)
		if err != nil {
			log.Errorf("更新索引失败: %+v", err)
		}
	}()
	common.SuccessResp(c)
}

// StopIndex 停止正在进行的索引构建
func StopIndex(c *gin.Context) {
	quit := search.Quit.Load()
	if quit == nil {
		common.ErrorStrResp(c, "当前没有正在构建的索引", 400)
		return
	}
	select {
	case *quit <- struct{}{}:
	default:
	}
	common.SuccessResp(c)
}

// ClearIndex 清除所有索引
func ClearIndex(c *gin.Context) {
	if search.Running() {
		common.ErrorStrResp(c, "索引正在构建中", 400)
		return
	}
	search.Clear(c)
	search.WriteProgress(&model.IndexProgress{
		ObjCount:     0,      // 对象数量归零
		IsDone:       true,   // 标记为已完成
		LastDoneTime: nil,    // 最后完成时间置空
		Error:        "",     // 错误信息清空
	})
	common.SuccessResp(c)
}

// GetProgress 获取索引构建进度
func GetProgress(c *gin.Context) {
	progress, err := search.Progress()
	if err != nil {
		common.ErrorResp(c, err, 500)
		return
	}
	common.SuccessResp(c, progress)
}
